﻿#include "DAWorkFlowPluginManager.h"
#include "DAAbstractNodePlugin.h"
#include "DAAbstractPlugin.h"
#include "DAPluginManager.h"
#include "DAAbstractNodeFactory.h"

class _DAAbstractNodePluginData
{
public:
    _DAAbstractNodePluginData();
    ~_DAAbstractNodePluginData();
    DAAbstractNodePlugin *plugin = { nullptr };
    DAAbstractNodeFactory *factory = { nullptr };
};
_DAAbstractNodePluginData::_DAAbstractNodePluginData() {}

_DAAbstractNodePluginData::~_DAAbstractNodePluginData()
{
    if (plugin && factory) {
        plugin->destoryNodeFactory(factory);
    }
}

DAWorkFlowPluginManager::DAWorkFlowPluginManager(QObject *p) : QObject(p)
{
    //加载插件
    DAPluginManager &plugin = DAPluginManager::instance();

    if (!plugin.isLoaded()) {
        plugin.load();
    }
    //获取插件
    QList<DAPluginOption> plugins = plugin.getPluginOptions();

    for (int i = 0; i < plugins.size(); ++i) {
        DAPluginOption opt = plugins[i];
        if (!opt.isValid()) {
            continue;
        }
        DAAbstractPlugin *p = opt.plugin();
        //开始通过dynamic_cast判断插件的具体类型
        if (DAAbstractNodePlugin *np = dynamic_cast<DAAbstractNodePlugin *>(p)) {
            //说明是节点插件
            _DAAbstractNodePluginData *data = new _DAAbstractNodePluginData();
            data->plugin = np;
            data->factory = np->createNodeFactory();
            m_nodePlugins.append(data);
            qDebug() << tr("succeed load plugin ") << np->getName();
        }
    }
}

DAWorkFlowPluginManager::~DAWorkFlowPluginManager()
{
    for (_DAAbstractNodePluginData *d : m_nodePlugins) {
        delete d;
    }
}

DAWorkFlowPluginManager &DAWorkFlowPluginManager::instance()
{
    static DAWorkFlowPluginManager s_mgr;

    return (s_mgr);
}

/**
 * @brief 获取所有的节点插件
 * @return
 */
QList<DAAbstractNodePlugin *> DAWorkFlowPluginManager::getNodePlugins() const
{
    QList<DAAbstractNodePlugin *> res;

    for (_DAAbstractNodePluginData *d : m_nodePlugins) {
        res.append(d->plugin);
    }
    return (res);
}

/**
 * @brief 获取所有的节点工厂
 * @return
 */
QList<DAAbstractNodeFactory *> DAWorkFlowPluginManager::getNodeFactorys() const
{
    QList<DAAbstractNodeFactory *> res;

    for (_DAAbstractNodePluginData *d : m_nodePlugins) {
        res.append(d->factory);
    }
    return (res);
}
